using System;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;

namespace My.IdlConverter.Core
{
    using Types;

    public enum ParamAttribute
    {
        Unknown = 0x00,
        In = 0x01,
        Out = 0x02,
        InOut = 0x03
    }

    public class Parameter
    {
        private IType _type;
        private string _name;
        private string _defaultValue;
        private Method _parentMethod;

        public Parameter()
        {
        }

        public Parameter(IType type, string name)
            :this(type,name,"")
        {
        }

        public Parameter(IType type, string name, string defaultValue)
        {
            _type = type;
            _name = name;
            _defaultValue = defaultValue;
        }

        public virtual ParamAttribute Attribute
        {
            get
            {
                if (Type.AbsoluteRef)
                {
                    bool isAllRef = false;
                    foreach (Parameter nextParam in Parent.Parameters)
                    {
                        if (nextParam.Type.AbsoluteRef)
                        {
                            isAllRef = true;
                            continue;
                        }
                        else
                        {
                            isAllRef = false;
                            break;
                        }
                    }
                    if (isAllRef)
                        return ParamAttribute.InOut;
                    else
                        return ParamAttribute.Out;
                }
                else if (!Type.Ref || Type.ConstRef)
                    return ParamAttribute.In;
                else
                {
                    Debug.Assert(false);
                    return ParamAttribute.Unknown;
                }
            }
            set { throw new Exception("No Edit"); }
        }

        public Method Parent
        {
            get
            {
                return _parentMethod;
            }
            set
            {
                _parentMethod = value;
            }
        }

        public IType Type
        {
            get{return _type;}
            set{_type = value;}
        }

        public string Name
        {
            get{return _name;}
            set{_name = value;}
        }

        public string DefaultValue
        {
            get
            {
                return _defaultValue;
            }
            set
            {
                _defaultValue = value;
            }
        }

        public bool HasDefaultValue
        {
            get
            {
                return _defaultValue.Length > 0;
            }
        }

        public override bool Equals(object obj)
        {
            Parameter other = obj as Parameter;
            if (other == null)
                return false;
            if (this == other)
                return true;

            return Declaration.Equals(other.Declaration);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public string Declaration
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("Type=" + Type.TypeString.Trim());
                sb.Append("\n");
                sb.Append("Default=" + DefaultValue.Trim());
                return sb.ToString();
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Type=" + Type.TypeString.Trim());
            sb.Append("\n");
            sb.Append("Name=" + Name);
            sb.Append("\n");
            sb.Append("Default=" + DefaultValue);
            return sb.ToString();
        }
    }
}
